import React, { useCallback, useState, useEffect, useRef, useMemo } from 'react';
import { Input, Button } from 'antd';
import { Common } from 'UtilsCommon';
import { Icon } from 'Configs';
import SpanText from './spanText';
import Base from './base';
import styles from '../styles/view.scss';

const validateFile = (file, property, pageAxis) => {
    if (property.acceptType) {
        const reg = new RegExp(property.acceptType, "i");

        const names = file.name.split('.');
        const ft = '.' + names[names.length - 1];

        if (!reg.test(ft)) {
            pageAxis.showMessage('请上传' + property.acceptType + '文件！');
            return false;
        }
    }

    if (property.fileSize > 0 && file.size > property.fileSize) {
        if (!property.fileSizeText) property.fileSizeText = Common.getFileSizeText(property.fileSize);
        pageAxis.showMessage('上传文件大小不能大于' + property.fileSizeText + '！');
        return false;
    }

    return true;
};

const invokeUploadFile = (fileInput, file, pageAxis, property, setValue, setLoading, width, height) => {
    const formData = new FormData();
    formData.append('file', file, file.name);

    let pathQuery = "";

    if (property.isImage) pathQuery += `?width=${width}&height=${height}`;

    if (property.getParameter) {
        const parameters = pageAxis.getFunction(property.getParameter);
        if (parameters) pathQuery += parameters();
    }

    setLoading(true);

    if (!property.serviceInterface) {
        property.serviceInterface = {
            serviceName: property.serviceName || 'FileService',
            actionName: property.isImage ? "uploadImage" : 'uploadFile'
        };
    }
    const { serviceName, actionName } = property.serviceInterface;

    pageAxis.dispatchAction(serviceName, actionName, { pathQuery, formData }).then(res => {
        if (pageAxis.isSuccessProps(res)) {
            if (property.uploadCallback) {
                const uploadCallback = pageAxis.getFunction(property.uploadCallback);
                if (uploadCallback) uploadCallback(res);
            }
            else setValue(res.FileUrl);
        }
        else pageAxis.alert(res.message);

        setLoading(false);
        fileInput.value = '';
    });
};

const uploadFile = (e, pageAxis, property, setValue, setLoading) => {
    const fileInput = e.target;
    if (fileInput.files.length === 0) return;

    const file = fileInput.files[0];
    if (!validateFile(file, property, pageAxis)) {
        fileInput.value = '';
        return;
    }

    if (property.isImage) {
        Common.getImageFileWidthHeight(file).then(res => {
            invokeUploadFile(fileInput, file, pageAxis, property, setValue, setLoading, res.width, res.height);
        });
    }
    else invokeUploadFile(fileInput, file, pageAxis, property, setValue, setLoading);
};

const reneraddonAfter = (property, pageId, value) => {
    if (property.isValueAddonAfter && Common.isNullOrEmpty(value)) return null;
    if (property.addonAfterButton) return <SpanText property={property.addonAfterButton} view={property} pageId={pageId} />;

    return property.addonAfter;
};

export default (props) => {
    const { property, pageAxis, pageId } = Base.getProps(props);

    const [isVisible, setIsVisible] = useState(property.isVisible !== false);
    const obj = useMemo(() => ({}), []);
    const [value, setValue] = useState(Base.getInitValue(property, obj) || '');
    const [disabled, setDisabled] = useState(!!property.disabled);
    const [isReadOnly, setIsReadOnly] = useState(!!property.isReadOnly);
    const [loading, setLoading] = useState(false);

    const onChangeText = useCallback((e) => {
        setValue(e.target.value);
    }, [setValue]);

    const inputFile = useRef(null);

    const onChange = useCallback((e) => {
        uploadFile(e, pageAxis, property, setValue, setLoading);
    }, [pageAxis, property, setValue, setLoading]);

    const onClick = useCallback(() => {
        inputFile.current.click();
    }, [inputFile]);

    useEffect(() => {
        Base.bindDataValue(property, value);
    }, [property, value]);

    property.setIsVisible = (v) => setIsVisible(v);
    property.setValue = (v) => setValue(v);
    property.getValue = () => value;
    property.setDisabled = (v) => setDisabled(v);
    property.setIsReadOnly = (v) => setIsReadOnly(v);

    if (!isVisible) return null;

    const isTextVisible = property.isTextVisible !== false;

    const { accept } = property;

    return (
        <div className={styles.divUploadText}>
            {isTextVisible && <Input placeholder={property.placeHolder}
                onChange={onChangeText}
                maxLength={property.maxLength}
                readOnly={isReadOnly}
                disabled={disabled && !isReadOnly}
                addonAfter={reneraddonAfter(property, pageId, value)}
                type='text'
                value={value} />}
            {isTextVisible && <div className={styles.divWhiteSapce}></div>}
            <div className={styles.divButton}>
                <Button disabled={disabled || isReadOnly} loading={loading} onClick={onClick} style={property.buttonStyle}>
                    <Icon type='upload' /> 上传
                </Button>
                {property.tip && <div className={styles.divTip}><span>{property.tip}</span></div>}
            </div>
            <input type='file' accept={accept} onChange={onChange} ref={inputFile} style={{ display: 'none' }} />
        </div>
    );
};